package inabit.compiler.parser.grammar;

import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.List;

/**Represents a production rule of context-free grammar*/
/**@author Rafael Rocha*/
public abstract class Production implements Cloneable{
	
	private NonTerminal nonTerminal;
	
	/**Constructor receives the label of the nonTerminal which is derived
	 * by the rule*/
	public Production(String label) {
		this.nonTerminal = new NonTerminal(label);
	}
	public NonTerminal getNonTerminal() {
		return nonTerminal;
	}
	
	/**Returns the sequence of symbols derived this production rule
	 * @throws Exception */
	public List<Symbol> derive(NonTerminal nonTerminal){
		if(!nonTerminal.getLabel().equals(this.nonTerminal.getLabel())) {
			throw new InvalidParameterException(
					"The non terminal " + nonTerminal.getLabel() +
					" to be derived is incompatible with the production's" +
					" non terminal " + this.nonTerminal.getLabel());
		}
		List<Symbol> symbols = new ArrayList<Symbol>();
		for(Symbol s : production(nonTerminal)) {
			symbols.add(s);
		}
		return symbols;
	}
	
	public List<Symbol> getProductionSymbols() {
		return derive(nonTerminal);
	}
	
	/**Returns the list of symbols of this production in the order of the production
	 *  derivation, if something goes wrong it must throw an exception with the
	 *  reason*/
	protected abstract Symbol[] production(final NonTerminal nonTerminal);
}
